<?xml version="1.0" encoding="UTF-8" ?>
<!--

    Copyright Camunda Services GmbH and/or licensed to Camunda Services GmbH
    under one or more contributor license agreements. See the NOTICE file
    distributed with this work for additional information regarding copyright
    ownership. Camunda licenses this file to you under the Apache License,
    Version 2.0; you may not use this file except in compliance with the License.
    You may obtain a copy of the License at

        http://www.apache.org/licenses/LICENSE-2.0

    Unless required by applicable law or agreed to in writing, software
    distributed under the License is distributed on an "AS IS" BASIS,
    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    See the License for the specific language governing permissions and
    limitations under the License.

-->
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd"> 

<mapper namespace="org.camunda.bpm.engine.history.HistoricActivityStatistics">

  <!-- RESULTMAP -->

  <resultMap id="historicActivityStatisticsResultMap" type="org.camunda.bpm.engine.impl.persistence.entity.HistoricActivityStatisticsImpl">
    <id property="id" column="ID_" jdbcType="VARCHAR" />
    <result property="instances" column="INSTANCE_COUNT_" jdbcType="INTEGER" />
    <result property="finished" column="FINISHED_COUNT_" jdbcType="INTEGER" />
    <result property="canceled" column="CANCELED_COUNT_" jdbcType="INTEGER" />
    <result property="completeScope" column="COMPLETE_SCOPE_COUNT_" jdbcType="INTEGER" />
    <result property="openIncidents" column="OPEN_INCIDENT_COUNT_" jdbcType="INTEGER" />
    <result property="resolvedIncidents" column="RESOLVED_INCIDENT_COUNT_" jdbcType="INTEGER" />
    <result property="deletedIncidents" column="DELETED_INCIDENT_COUNT_" jdbcType="INTEGER" />
  </resultMap>

  <resultMap id="historicCaseActivityStatisticsResultMap" type="org.camunda.bpm.engine.impl.persistence.entity.HistoricCaseActivityStatisticsImpl">
    <id property="id" column="ID_" jdbcType="VARCHAR" />
    <result property="available" column="AVAILABLE_" jdbcType="INTEGER" />
    <result property="enabled" column="ENABLED_" jdbcType="INTEGER" />
    <result property="disabled" column="DISABLED_" jdbcType="INTEGER" />
    <result property="active" column="ACTIVE_" jdbcType="INTEGER" />
    <result property="terminated" column="TERMINATED_" jdbcType="INTEGER" />
    <result property="completed" column="COMPLETED_" jdbcType="INTEGER" />
  </resultMap>

  <!-- HistoricActivity statistics -->

  <select id ="selectHistoricActivityStatistics" resultMap="historicActivityStatisticsResultMap" 
    parameterType="org.camunda.bpm.engine.impl.HistoricActivityStatisticsQueryImpl">
    <include refid="org.camunda.bpm.engine.impl.persistence.entity.Commons.bindOrderBy"/>
    ${limitBefore}
    select RES.*
    ${limitBetween}
    <include refid="selectHistoricActivityStatisticsByQueryCriteriaSql"/>
    ${orderBy}
    ${limitAfter}
  </select>

  <select id ="selectHistoricActivityStatisticsCount" resultType="long" 
    parameterType="org.camunda.bpm.engine.impl.HistoricActivityStatisticsQueryImpl">
    ${countDistinctBeforeStart} RES.ID_ ${countDistinctBeforeEnd}
    <include refid="selectHistoricActivityStatisticsByQueryCriteriaSql"/>
    ${countDistinctAfterEnd}
  </select>

  <sql id="selectHistoricActivityStatisticsByQueryCriteriaSql">
    from (

      <!-- in case of fetching the incidents number ("includeIncidents")
           a UNION and second aggregation are required for the final result -->
      <if test="includeIncidents">
      select ID_,
        sum(INSTANCE_COUNT_) as INSTANCE_COUNT_
        <if test="includeFinished">
        , sum(FINISHED_COUNT_) as FINISHED_COUNT_
        </if>
        <if test="includeCanceled">
        , sum(CANCELED_COUNT_) as CANCELED_COUNT_
        </if>
        <if test="includeCompleteScope">
        , sum(COMPLETE_SCOPE_COUNT_) as COMPLETE_SCOPE_COUNT_
        </if>
        <if test="includeIncidents">
        , sum(OPEN_INCIDENT_COUNT_) as OPEN_INCIDENT_COUNT_
        , sum(RESOLVED_INCIDENT_COUNT_) as RESOLVED_INCIDENT_COUNT_
        , sum(DELETED_INCIDENT_COUNT_) as DELETED_INCIDENT_COUNT_
        </if>
      from (
      </if>

          select ACT.ACT_ID_ as ID_,
            sum(CASE WHEN ACT.END_TIME_ is NULL THEN 1 ELSE 0 END) as INSTANCE_COUNT_
            <if test="includeFinished">
            , sum(CASE WHEN ACT.END_TIME_ is not NULL THEN 1 ELSE 0 END) as FINISHED_COUNT_
            </if>
            <if test="includeCanceled">
            , sum(CASE WHEN ACT.ACT_INST_STATE_ = 2 THEN 1 ELSE 0 END) as CANCELED_COUNT_
            </if>
            <if test="includeCompleteScope">
            , sum(CASE WHEN ACT.ACT_INST_STATE_ = 1 THEN 1 ELSE 0 END) as COMPLETE_SCOPE_COUNT_
            </if>
            <if test="includeIncidents">
            , 0${numericCast} as OPEN_INCIDENT_COUNT_
            , 0${numericCast} as RESOLVED_INCIDENT_COUNT_
            , 0${numericCast} as DELETED_INCIDENT_COUNT_
            </if>

          from ${prefix}ACT_HI_ACTINST ACT

          <if test="startedBefore != null || startedAfter != null || finishedBefore != null || finishedAfter != null">
            INNER JOIN ${prefix}ACT_HI_PROCINST PI
            ON ACT.PROC_INST_ID_ = PI.ID_
          </if>

          where ACT.PROC_DEF_ID_ = #{processDefinitionId}
            <if test="!includeFinished">
              and (
                ACT.END_TIME_ is null
              <if test="includeCanceled">
                or ACT.ACT_INST_STATE_ = 2
              </if>
              <if test="includeCompleteScope">
                or ACT.ACT_INST_STATE_ = 1
              </if>
              )
            </if>

          <include refid="applyStatisticsFilters" />

          <if test="processInstanceIds != null">
            and ACT.PROC_INST_ID_ in
            <foreach item="processInstanceId" index="index" collection="processInstanceIds"
                open="(" separator="," close=")">
              #{processInstanceId}
            </foreach>
          </if>

          GROUP BY ACT_ID_

      <if test="includeIncidents">
        UNION
            select
              INC.ACTIVITY_ID_ as ID_,
              0${numericCast} as INSTANCE_COUNT_
              <if test="includeFinished">
              , 0${numericCast} as FINISHED_COUNT_
              </if>
              <if test="includeCanceled">
              , 0${numericCast} as CANCELED_COUNT_
              </if>
              <if test="includeCompleteScope">
              , 0${numericCast} as COMPLETE_SCOPE_COUNT_
              </if>
              , sum(CASE WHEN INC.INCIDENT_STATE_ = 0 THEN 1 ELSE 0 END) as OPEN_INCIDENT_COUNT_
              , sum(CASE WHEN INC.INCIDENT_STATE_ = 1 THEN 1 ELSE 0 END) as RESOLVED_INCIDENT_COUNT_
              , sum(CASE WHEN INC.INCIDENT_STATE_ = 2 THEN 1 ELSE 0 END) as DELETED_INCIDENT_COUNT_
            from ${prefix}ACT_HI_INCIDENT INC

            <if test="startedBefore != null || startedAfter != null || finishedBefore != null || finishedAfter != null">
              INNER JOIN ${prefix}ACT_HI_PROCINST PI
              ON INC.PROC_INST_ID_ = PI.ID_
            </if>

            where INC.PROC_DEF_ID_ = #{processDefinitionId}

            <include refid="applyStatisticsFilters" />

            <if test="processInstanceIds != null">
              and INC.PROC_INST_ID_ in
              <foreach item="processInstanceId" index="index" collection="processInstanceIds"
                  open="(" separator="," close=")">
                #{processInstanceId}
              </foreach>
            </if>

            GROUP BY INC.ACTIVITY_ID_
      ) RES
      GROUP BY ID_
      </if>

    ) RES
  </sql>

  <sql id="applyStatisticsFilters">
    <if test="startedBefore != null">
      and PI.START_TIME_ &lt;= #{startedBefore}
    </if>
    <if test="startedAfter != null">
      and PI.START_TIME_ &gt;= #{startedAfter}
    </if>
    <if test="finishedBefore != null">
      and PI.END_TIME_ &lt;= #{finishedBefore}
    </if>
    <if test="finishedAfter != null">
      and PI.END_TIME_ &gt;= #{finishedAfter}
    </if>
  </sql>

  <!-- HistoricCaseActivity statistics -->

  <select id ="selectHistoricCaseActivityStatistics" resultMap="historicCaseActivityStatisticsResultMap" 
    parameterType="org.camunda.bpm.engine.impl.HistoricCaseActivityStatisticsQueryImpl">
    <include refid="org.camunda.bpm.engine.impl.persistence.entity.Commons.bindOrderBy"/>
    ${limitBefore}
    select RES.*
    ${limitBetween}
    <include refid="selectHistoricCaseActivityStatisticsByQueryCriteriaSql"/>
    ${orderBy}
    ${limitAfter}
  </select>

  <select id ="selectHistoricCaseActivityStatisticsCount" resultType="long" 
    parameterType="org.camunda.bpm.engine.impl.HistoricCaseActivityStatisticsQueryImpl">
    ${countDistinctBeforeStart} RES.ID_ ${countDistinctBeforeEnd}
    <include refid="selectHistoricCaseActivityStatisticsByQueryCriteriaSql"/>
    ${countDistinctAfterEnd}
  </select>

  <sql id="selectHistoricCaseActivityStatisticsByQueryCriteriaSql">
    from (
      select
        HCAI.CASE_ACT_ID_ as ID_
      , count( CASE WHEN HCAI.STATE_ = 1 THEN 1 ELSE null END ) as AVAILABLE_
      , count( CASE WHEN HCAI.STATE_ = 2 THEN 1 ELSE null END ) as ENABLED_
      , count( CASE WHEN HCAI.STATE_ = 3 THEN 1 ELSE null END ) as DISABLED_
      , count( CASE WHEN HCAI.STATE_ = 4 THEN 1 ELSE null END ) as ACTIVE_
      , count( CASE WHEN HCAI.STATE_ = 6 THEN 1 ELSE null END ) as TERMINATED_
      , count( CASE WHEN HCAI.STATE_ = 7 THEN 1 ELSE null END ) as COMPLETED_
      from
        ${prefix}ACT_HI_CASEACTINST HCAI
      where
        HCAI.CASE_DEF_ID_ = #{caseDefinitionId}
      group by HCAI.CASE_ACT_ID_
    ) RES
  </sql>

</mapper>
